#include "public.hpp"
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>

const int blags = 16;

class TcpServer;
using task_t = function<void()>;

class Data
{
public:
    int _sockfd;
    Analyze _an;
    TcpServer *self;

    Data(int sockfd, Analyze an, TcpServer *p) : _sockfd(sockfd), _an(an), self(p)
    {
    }
};

class TcpServer
{
private:
    uint16_t _port; // 服务端端口号
    int _listensockfd;

public:
    TcpServer(uint16_t port) : _port(port)
    {
    }

    void Init()
    {
        _listensockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (_listensockfd < 0)
        {
            Log(Fatal, "socket create error");
            exit(SOCK_CREATE_ERROR);
        }
        // socket创建成功

        // 接下来需要将socket与网络信息进行绑定
        struct sockaddr_in server;
        bzero(&server, sizeof(server));

        server.sin_addr.s_addr = 0; // 表示绑定本机任意ip地址
        server.sin_family = AF_INET;
        server.sin_port = htons(_port);

        socklen_t len = sizeof(server);
        int bindval = bind(_listensockfd, (struct sockaddr *)&server, len);
        if (bindval < 0)
        {
            Log(Fatal, "socket bind error");
            exit(SOCK_BIND_ERROR);
        }
        // 绑定成功
        Log(Info, "socket init success");

        // 监听
        int n = listen(_listensockfd, blags);
        if (n < 0)
        {
            Log(Fatal, "listen error");
            exit(SOCK_LISTEN_ERROR);
        }
        Log(Debug, "listen success");
    }

    void Service(int fd, Analyze peer)
    {
        string clientinfo = "[" + peer.getip() + ":" + to_string(peer.getport()) + "]";

        char buffer[1024];
        while (true)
        {
            bzero(buffer, sizeof(buffer));
            ssize_t n = read(fd, buffer, sizeof(buffer));
            if (n > 0)
            {
                cout << clientinfo << ": " << buffer << endl;

                string response = "server echo: ";
                response += buffer;
                write(fd, response.c_str(), response.size());
            }
            else if (n == 0)
            {
                Log(Info, "%s quit", clientinfo.c_str());
                break;
            }
            else
            {
                break;
            }
        }

        close(fd);
        // ::close(fd);
    }

    // version 0
    //  void Start()
    //  {
    //      while(true)
    //      {
    //          struct sockaddr_in peer;
    //          socklen_t len = sizeof(peer);

    //         //接收连接请求
    //         int fd = accept(_listensockfd, (struct sockaddr*)&peer, &len);
    //         Log(Info, "accept success");
    //         if(fd < 0)
    //         {
    //             Log(Warning, "accept fail");
    //             continue;
    //         }
    //         //处理该连接请求
    //         Service(fd, Analyze(peer));
    //     }
    // }

    // version 1
    //  void Start()
    //  {
    //      signal(SIGCHLD, SIG_IGN);

    //     while(true)
    //     {
    //         struct sockaddr_in peer;
    //         socklen_t len = sizeof(peer);

    //         //接收连接请求
    //         int fd = accept(_listensockfd, (struct sockaddr*)&peer, &len);
    //         Log(Info, "accept success");
    //         if(fd < 0)
    //         {
    //             Log(Warning, "accept fail");
    //             continue;
    //         }
    //         //处理该连接请求

    //         int id = fork();
    //         if(id == 0)
    //         {
    //             close(_listensockfd);
    //             Service(fd, Analyze(peer));
    //             exit(0);
    //         }

    //         close(fd);
    //     }
    // }

    // version 2
    // void Start()
    // {
    //     while (true)
    //     {
    //         struct sockaddr_in peer;
    //         socklen_t len = sizeof(peer);

    //         // 接收连接请求
    //         int fd = accept(_listensockfd, (struct sockaddr *)&peer, &len);
    //         Log(Info, "accept success");
    //         if (fd < 0)
    //         {
    //             Log(Warning, "accept fail");
    //             continue;
    //         }
    //         // 处理该连接请求

    //         int id = fork();
    //         if (id == 0)
    //         {
    //             close(_listensockfd);

    //             if (fork() > 0)
    //                 exit(0); // 服务进程的子进程退出
    //             Service(fd, Analyze(peer));
    //             exit(0); // 孙子进程处理请求后退出
    //         }

    //         waitpid(id, nullptr, 0);
    //     }
    // }

    // static void *func(void* args)
    // {
    //     pthread_detach(pthread_self());

    //     Data* p = static_cast<Data*>(args);
    //     p->self->Service(p->_sockfd, p->_an);

    //     delete p;
    //     return nullptr;
    // }
    // //version 3
    // void Start()
    // {
    //     while (true)
    //     {
    //         struct sockaddr_in peer;
    //         socklen_t len = sizeof(peer);

    //         // 接收连接请求
    //         int fd = accept(_listensockfd, (struct sockaddr *)&peer, &len);
    //         Log(Info, "accept success");
    //         if (fd < 0)
    //         {
    //             Log(Warning, "accept fail");
    //             continue;
    //         }

    //         // 处理该连接请求
    //         pthread_t thread;
    //         Data *data = new Data(fd, Analyze(peer), this);

    //         pthread_create(&thread,nullptr, func, data);
    //     }
    // }

    //version 4
    void Start()
    {
        while (true)
        {
            struct sockaddr_in peer;
            socklen_t len = sizeof(peer);

            // 接收连接请求
            int fd = accept(_listensockfd, (struct sockaddr *)&peer, &len);
            Log(Info, "accept success");
            if (fd < 0)
            {
                Log(Warning, "accept fail");
                continue;
            }

            // 处理该连接请求
            task_t t = bind(&TcpServer::Service, this, fd, Analyze(peer));
            ThreadPool<task_t> *Pool = ThreadPool<task_t>::GetPool();
            Pool->ThreadInit();
            Pool->Start();
            Pool->Push(t);
        }
    }

    ~TcpServer() {}
};
